package com.mhtvs;


import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import com.mhtvs.MhtvsActivity;
import com.mhtvs.R;
import com.mhtvs.Database.PortForwards;
import com.mhtvs.Database.Servers;

//---------------------------------------------------------------
//Development source for MHTVS CLIENT
//"Android client for use with MHTVS"
//Copyright (c) 2011, Doug Thompson, perladdict@gmail.com
//All rights reserved.
//
//http://code.google.com/p/mhtvs/
//
//View Demo here:
//http://www.youtube.com/watch?v=v4M2uVrMrGk
//
//Redistribution and use in source and binary forms, with or
//without modification, are permitted provided that the following
//conditions are met:
//
//* Redistributions of source code must retain the above
//  copyright notice, this list of conditions and the
//  following disclaimer.
//* Redistributions in binary form must reproduce the
//  above copyright notice, this list of conditions and
//  the following disclaimer in the documentation and/or
//  other materials provided with the distribution.
//* Neither the name of the developer nor the names
//  of its contributors may be used to endorse or promote
//  products derived from this software without specific
//  prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
//CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
//INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
//MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
//DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
//SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
//WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
//OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
//SUCH DAMAGE.
//---------------------------------------------------------------


// Server List Screen

public class ListServers extends MhtvsActivity {
	private static Context context;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.server_list_view);
		fillServerList();
	}
		
    // DIALOGS
	public interface Command {
		public void execute();
		public static final Command NO_OP = new Command() { public void execute() {} };
	}
	
	public static class CommandWrapper implements DialogInterface.OnClickListener {
		  private Command command;
		  public CommandWrapper(Command command) {
		    this.command = command;
		  }

		  @Override
		  public void onClick(DialogInterface dialog, int which) {
		    dialog.dismiss();
		    command.execute();
		  }
	}
	    
	private static final CommandWrapper DISMISS = new CommandWrapper(Command.NO_OP);

	public static AlertDialog createDeletionDialog(final Context context, final Command deleteCommand) {
		AlertDialog.Builder builder = new AlertDialog.Builder(context);
		builder.setCancelable(true);
		//builder.setIcon(R.drawable.dialog_question);
		builder.setTitle("Confirm deletion?");
		builder.setInverseBackgroundForced(true);
		builder.setPositiveButton("Delete", new CommandWrapper(deleteCommand));
		builder.setNegativeButton("Dismiss", DISMISS);
		return builder.create();
	}
	
	public void fillServerList() {
		// TableLayout where we want to Display list
		final TableLayout serverTable = (TableLayout) findViewById(R.id.TableLayout_ServerList);
		// SQL Query
		SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
		queryBuilder.setTables(Servers.SERVER_TABLE_NAME);

		// Get the database and run the query
        SQLiteDatabase db = mDatabase.getReadableDatabase();
        String asColumnsToReturn[] = { 
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_DESCRIPTION, 
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_ADDRESS,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_INTERNAL_ADDRESS,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_ID, 
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_ACTIVE_STATE,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_ACTIVE_INTERNAL_STATE,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_PAGE,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_USER,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_PORT
        };

        final Cursor c = queryBuilder.query(db, asColumnsToReturn, null, null, null, null, Servers.DEFAULT_SORT_ORDER);
        // Display the results by adding some TableRows to the existing table layout
		if(c.moveToFirst()) {
			for(int i = 0; i< c.getCount(); i++) {
				TableRow newRow = new TableRow(this);
				TextView address = new TextView(this);
				TextView description = new TextView(this);
				Button deleteButton = new Button(this);
				deleteButton.setText("del");
				deleteButton.setTextSize(8);
			    deleteButton.setMaxHeight(10);
				deleteButton.setTag(c.getInt(c.getColumnIndex(Servers.SERVER_ID)));			
				deleteButton.setOnClickListener(new View.OnClickListener() {
					@Override
					public void onClick(final View v) {		
					    Command delete = new Command() {
					    	public void execute() {
					    		// Delete that Server
								Integer id = (Integer) v.getTag();
								deleteServer(id);
								// Find and destroy the row tagged with the deleted server id in the Table 
								final TableLayout serverTable = (TableLayout) findViewById(R.id.TableLayout_ServerList);
								// This should return the TableRow as the first tagged view in the layout but it would be nice if it returned an array of views with that tag...
								View viewToDelete = serverTable.findViewWithTag(id);
								serverTable.removeView(viewToDelete);
						    }
					    };
					    AlertDialog deletionDialog = ListServers.createDeletionDialog(ListServers.this, delete);
					    deletionDialog.show();
					}
				});
				
				Button portForwardButton = new Button(this);
				portForwardButton.setText("ports");
				portForwardButton.setTextSize(8);
				portForwardButton.setMaxHeight(10);
				portForwardButton.setTag(c.getInt(c.getColumnIndex(Servers.SERVER_ID)));
				portForwardButton.setOnClickListener(new View.OnClickListener() {
					public void onClick(View v) {
						// Add Port Forwards
						Integer id = (Integer) v.getTag();
						addPortForward(id);
					}
				});					
						
				Button detailsButton = new Button(this);
				detailsButton.setText("details");
				detailsButton.setTextSize(8);
				detailsButton.setMaxHeight(10);
				detailsButton.setTag(c.getInt(c.getColumnIndex(Servers.SERVER_ID)));
				detailsButton.setOnClickListener(new View.OnClickListener() {
					public void onClick(View v) {
						// Add Port Forwards
						Integer id = (Integer) v.getTag();
						addDetails(id);
					}
				});		

				newRow.setTag(c.getInt(c.getColumnIndex(Servers.SERVER_ID)));
				
				address.setTextSize(10);
				description.setTextSize(10);
				
				
				// keep server address under 10 chars
				String address1 = c.getString(c.getColumnIndex(Servers.SERVER_ADDRESS));
				if (address1.length() > 11 ) {
					String address2 = address1.substring(0,10);
					String address3 = address2 + "...";
					address.setText(address3);
				} else {
					String address3 = address1;
					address.setText(address3);
				}
				
				//address.setText(c.getString(c.getColumnIndex(Servers.SERVER_ADDRESS)));
				
				description.setText(c.getString(c.getColumnIndex(Servers.SERVER_DESCRIPTION)));
				
				newRow.addView(address);
				//newRow.addView(description);
				newRow.addView(deleteButton);
				newRow.addView(portForwardButton);
				newRow.addView(detailsButton);
				serverTable.addView(newRow);
				c.moveToNext();
			}
		} else {
			TableRow newRow = new TableRow(this);
			TextView noResults = new TextView(this);
			noResults.setTextSize(8);
            noResults.setText("No server entries found. Return to entry screen and add your configuration.");
			newRow.addView(noResults);
			serverTable.addView(newRow);
		}
		c.close();
		db.close();	
	
		// Handle Go to List button
		final Button gotoList = (Button) findViewById(R.id.ButtonShowEntry);
		gotoList.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				// Go to other activity that displays pet list
				startActivity(new Intent(getApplicationContext(), ServerEntry.class));
			}
		});
		
		// EDIT AND SAVE PRESET ENTRY		
		final Button saveServer = (Button) findViewById(R.id.ButtonSaveEdit);
		saveServer.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				final EditText ServerName = (EditText) findViewById(R.id.EditTextServerAddress);
				final EditText ServerDesc = (EditText) findViewById(R.id.EditTextServerDescription);
				final EditText ServerInternalName = (EditText) findViewById(R.id.EditTextServerInternalAddress);
				final EditText ServerPassword = (EditText) findViewById(R.id.EditTextServerPassword);
				final EditText ServerSaltPassword = (EditText) findViewById(R.id.EditTextServerSaltPassword);
				final EditText ServerPage = (EditText) findViewById(R.id.EditTextServerPage);
				final EditText ServerUser = (EditText) findViewById(R.id.EditTextServerUser);
				final EditText ServerPort = (EditText) findViewById(R.id.EditTextServerPort);				
				// Save new records
				//deleteDatabase("ssh_servers.db");
				SQLiteDatabase db = mDatabase.getWritableDatabase();
				//db = openOrCreateDatabase("ssh_servers.db",SQLiteDatabase.CREATE_IF_NECESSARY,null);
				db.beginTransaction();
				try {
					// check if species type exists already
					long rowId = 0;
					String strServerName = ServerName.getText().toString().toLowerCase();
					String strServerInternal = ServerInternalName.getText().toString().toLowerCase();
					String strServerDesc = ServerDesc.getText().toString().toLowerCase();
					String strServerPassword = ServerPassword.getText().toString().toLowerCase();
					String strServerSaltPassword = ServerSaltPassword.getText().toString().toLowerCase();
					String strServerPage = ServerPage.getText().toString().toLowerCase();
					String strServerUser = ServerUser.getText().toString().toLowerCase();
					String strServerPort = ServerPort.getText().toString().toLowerCase();
					// SQL Query
					SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
					queryBuilder.setTables(Servers.SERVER_TABLE_NAME);
					/////queryBuilder.appendWhere(Servers.SERVER_ADDRESS + "='" + strServerName + "'");
					// run the query
					Cursor c = queryBuilder.query(db, null, null, null, null, null, null);
					if (c.getCount() == 0) {
						// add the new type to our list
						//ContentValues typeRecordToAdd = new ContentValues();
						//typeRecordToAdd.put(Servers.SERVER_ADDRESS, strServerName);
						//rowId = db.insert(Servers.SERVER_TABLE_NAME,Servers.SERVER_ADDRESS, typeRecordToAdd);
						//typeRecordToAdd.put(Servers.SERVER_DESCRIPTION, strServerDesc);
						//rowId = db.insert(Servers.SERVER_TABLE_NAME,Servers.SERVER_DESCRIPTION, typeRecordToAdd);
					} else {
						c.moveToFirst();
						rowId = c.getLong(c.getColumnIndex(Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_ID));
					}
					c.close();
					// Always insert new server records, even if the names clash


					
					
					int checkBoxINT;
			        final CheckBox checkBox = (CheckBox) findViewById(R.id.checkBox1);
			        if (checkBox.isChecked()) {
			        	checkBoxINT = 1;
			        } else {
			        	checkBoxINT = 0;
			        }
			        
			        
			        
					int checkBoxBINT;
			        final CheckBox checkBoxB = (CheckBox) findViewById(R.id.checkBox2);
			        if (checkBoxB.isChecked()) {
			        	checkBoxBINT = 1;
			        } else {
			        	checkBoxBINT = 0;
			        }

			        
			        //TODO
			        //int PortEntry = Integer.getInteger(ServerPort.getText().toString());
			        
			        
					ContentValues ColumnsToUpdate = new ContentValues(); 
					ColumnsToUpdate.put(Servers.SERVER_ADDRESS, ServerName.getText().toString());
					ColumnsToUpdate.put(Servers.SERVER_DESCRIPTION, ServerDesc.getText().toString());
					ColumnsToUpdate.put(Servers.SERVER_INTERNAL_ADDRESS, ServerInternalName.getText().toString());
					ColumnsToUpdate.put(Servers.SERVER_PASSWORD, ServerPassword.getText().toString());
					ColumnsToUpdate.put(Servers.SERVER_SALT, ServerSaltPassword.getText().toString());
					ColumnsToUpdate.put(Servers.SERVER_PAGE, ServerPage.getText().toString());
					ColumnsToUpdate.put(Servers.SERVER_USER, ServerUser.getText().toString());
					
					//TODO
					//ColumnsToUpdate.put(Servers.SERVER_PORT, PortEntry);  // from PortEntry int above
					
					//ColumnsToUpdate.put(Servers.SERVER_PORT, Integer.getInteger(ServerPort.getText().toString()));					
					
					ColumnsToUpdate.put(Servers.SERVER_PORT, ServerPort.getText().toString());
					
					ColumnsToUpdate.put(Servers.SERVER_ACTIVE_STATE, checkBoxINT);
					ColumnsToUpdate.put(Servers.SERVER_ACTIVE_INTERNAL_STATE, checkBoxBINT);
					
					SharedPreferences prefsPrivate = getSharedPreferences(PREFS_PRIVATE, Context.MODE_PRIVATE);
					int PASSED_ID_KEY = Integer.parseInt(prefsPrivate.getString(KEY_PRIVATE, "serverid"));
					String whereClause = Servers.SERVER_ID + " = " + PASSED_ID_KEY;
					String whereArgs[] = {};
					db.update(Servers.SERVER_TABLE_NAME, ColumnsToUpdate, whereClause, whereArgs);
					db.setTransactionSuccessful();
				} finally {
					db.endTransaction();
				}

				// reset form
				ServerName.setText(null);
				ServerDesc.setText(null);
				ServerInternalName.setText(null);
				ServerSaltPassword.setText(null);
				ServerPassword.setText(null);
				ServerUser.setText(null);
				ServerPage.setText(null);
				ServerPort.setText(null);				
				final CheckBox checkBox = (CheckBox) findViewById(R.id.checkBox1);
				checkBox.setChecked(false);
				final CheckBox checkBox_B = (CheckBox) findViewById(R.id.checkBox2);
				checkBox_B.setChecked(false);
				
				db.close();
				startActivity(new Intent(getApplicationContext(), ListServers.class));	
			}
		});
	}
	
	
	public void addDetails(int id) {
		final EditText ServerName = (EditText) findViewById(R.id.EditTextServerAddress);
		final EditText ServerDesc = (EditText) findViewById(R.id.EditTextServerDescription);
		final EditText ServerPassword = (EditText) findViewById(R.id.EditTextServerPassword);
		final EditText ServerInternalName = (EditText) findViewById(R.id.EditTextServerInternalAddress);
		final EditText ServerSaltPassword = (EditText) findViewById(R.id.EditTextServerSaltPassword);
		final EditText ServerPage = (EditText) findViewById(R.id.EditTextServerPage);
		final EditText ServerUser = (EditText) findViewById(R.id.EditTextServerUser);
		final EditText ServerPort = (EditText) findViewById(R.id.EditTextServerPort);		
        final CheckBox checkBox = (CheckBox) findViewById(R.id.checkBox1);
        final CheckBox checkBox_b = (CheckBox) findViewById(R.id.checkBox2);
		SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
		queryBuilder.setTables(Servers.SERVER_TABLE_NAME);
		
		String sid = Integer.toString(id);
		SharedPreferences prefsPrivate = getSharedPreferences(PREFS_PRIVATE, Context.MODE_PRIVATE);
		Editor editor = prefsPrivate.edit();
		editor.putString(KEY_PRIVATE, sid);
		editor.commit();
		
		// WHERE CLAUSE:
		String inWhere = Servers.SERVER_ID + " = " + id;
		queryBuilder.appendWhere(inWhere);
        
		SQLiteDatabase db = mDatabase.getReadableDatabase();
        String asColumnsToReturn[] = { 
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_DESCRIPTION, 
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_ADDRESS, 
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_INTERNAL_ADDRESS,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_PASSWORD,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_SALT,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_USER,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_PORT,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_PAGE,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_PORTFORWARD_ID_KEY,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_ACTIVE_STATE,
        		Servers.SERVER_TABLE_NAME + "." + Servers.SERVER_ACTIVE_INTERNAL_STATE
        };
		
        Cursor c = queryBuilder.query(db, asColumnsToReturn, null, null, null, null, Servers.DEFAULT_SORT_ORDER);
		
        if(c.moveToFirst()) {
			for(int i = 0; i< c.getCount(); i++) {
				//String serverID = c.getString(c.getColumnIndex(Servers.SERVER_ID));
				String serverDESCRIPTION = c.getString(c.getColumnIndex(Servers.SERVER_DESCRIPTION));
				String serverADDRESS = c.getString(c.getColumnIndex(Servers.SERVER_ADDRESS));
				String serverSERVERINTERNAL = c.getString(c.getColumnIndex(Servers.SERVER_INTERNAL_ADDRESS));
				String serverPASSWORD = c.getString(c.getColumnIndex(Servers.SERVER_PASSWORD));
				String serverSALT = c.getString(c.getColumnIndex(Servers.SERVER_SALT));
				String serverUSER = c.getString(c.getColumnIndex(Servers.SERVER_USER));
				String serverPAGE = c.getString(c.getColumnIndex(Servers.SERVER_PAGE));
				int serverPORT = c.getInt(c.getColumnIndex(Servers.SERVER_PORT));				
//				String serverPFIDKEY = c.getString(c.getColumnIndex(Servers.SERVER_PORTFORWARD_ID_KEY));
				int serverACTIVE = c.getInt(c.getColumnIndex(Servers.SERVER_ACTIVE_STATE));
				int serverINTERNALACTIVE = c.getInt(c.getColumnIndex(Servers.SERVER_ACTIVE_INTERNAL_STATE));

				ServerName.setText(serverADDRESS, TextView.BufferType.EDITABLE);
				ServerDesc.setText(serverDESCRIPTION, TextView.BufferType.EDITABLE);
				ServerInternalName.setText(serverSERVERINTERNAL, TextView.BufferType.EDITABLE);
				ServerPassword.setText(serverPASSWORD, TextView.BufferType.EDITABLE);
				ServerSaltPassword.setText(serverSALT, TextView.BufferType.EDITABLE);
				ServerUser.setText(serverUSER, TextView.BufferType.EDITABLE);
				ServerPage.setText(serverPAGE, TextView.BufferType.EDITABLE);
				String serverPortString = Integer.toString(serverPORT);
				ServerPort.setText(serverPortString, TextView.BufferType.EDITABLE);				
				//if (serverACTIVE == 1) { } else { }
				checkBox.setChecked((serverACTIVE)==0? false:true);
				//if (serverINTERNALACTIVE) { } else { }
				checkBox_b.setChecked((serverINTERNALACTIVE)==0? false:true);
				
			}
		}
		c.close();
		db.close();	
	}
	
	
	// http://stackoverflow.com/questions/4426891/android-appwidget-sharedpreferences-crash
	public static Context ctx;
	private final static String saved_pref_file="saved_port_prefs";
	private static final String PREFS_PRIVATE = null;
	private static final String KEY_PRIVATE = null;
 
	public static void saveStringValue(String sName, String sValue, Context ctx) {
        SharedPreferences settings = ctx.getSharedPreferences(saved_pref_file, 0);
        SharedPreferences.Editor editor = settings.edit();
        editor.putString(sName, sValue);
        editor.commit();
   }

    public static String loadStringValue(String sName, Context ctx) {
        try {
            SharedPreferences settings = ctx.getSharedPreferences(saved_pref_file, 0);
            return settings.getString(sName,"");
        } catch (Exception ex) {    return "";      }
    }

    
	public void addPortForward(Integer id) {			
		String sid = Integer.toString(id);
		SharedPreferences prefsPrivate = getSharedPreferences(PREFS_PRIVATE, Context.MODE_PRIVATE);
		Editor editor = prefsPrivate.edit();
		editor.putString(KEY_PRIVATE, sid);
		editor.commit();
        startActivity(new Intent(getApplicationContext(), PortForwardsEntry.class));	
	}
		
	public void deleteServer(Integer id) {
        SQLiteDatabase db = mDatabase.getWritableDatabase();
		String astrArgs[] = { id.toString() };
        db.delete(Servers.SERVER_TABLE_NAME, Servers.SERVER_ID + "=?",astrArgs );
        db.delete(PortForwards.PORTFORWARDS_TABLE_NAME, PortForwards.PORTFORWARDS_ID_KEY + "=?",astrArgs );
        db.close();
	}
}